package com.xfcy.blog.config.satoken;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONObject;
import com.xfcy.blog.common.constant.RedisConstant;
import com.xfcy.blog.entity.UserAuth;
import com.xfcy.blog.mapper.UserAuthMapper;
import com.xfcy.blog.mapper.UserMapper;
import com.xfcy.blog.vo.LoginUserVO;
import eu.bitwalker.useragentutils.UserAgent;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import com.xfcy.blog.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义侦听器的实现
 * @author 晓风残月Lx
 * @date 2023/4/21 10:59
 */
@Component
public class MySaTokenListener implements SaTokenListener {

    private static final Logger logger = LoggerFactory.getLogger(MySaTokenListener.class);

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private UserAuthMapper userAuthMapper;

    @Resource
    private UserMapper userMapper;

    public static final List<LoginUserVO> ONLINE_USERS = new CopyOnWriteArrayList<>();

    /** 每次登录时触发 */
    @Override
    public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
        System.out.println("---------- 自定义侦听器实现 doLogin");
        // 修改登录信息
        String ipAddress = IpUtils.getIp(request);
        String ipSource = IpUtils.getCityInfo(ipAddress);
        UserAgent userAgent = IpUtils.getUserAgent(request);

        userMapper.updateLoginInfo(loginId,ipAddress,ipSource,userAgent.getOperatingSystem().getName(),userAgent.getBrowser().getName());

        UserAuth auth = userAuthMapper.getByUserId(Integer.parseInt(loginId.toString()));

        LoginUserVO loginUserVO =LoginUserVO.builder()
                .avatar(auth.getAvatar())
                .ip(ipAddress)
                .city(ipSource)
                .loginTime(LocalDateTime.now())
                .os(userAgent.getOperatingSystem().getName())
                .userId((Long) loginId)
                .tokenValue(tokenValue)
                .nickname(auth.getNickname())
                .browser(userAgent.getBrowser().getName())
                .build();

        ONLINE_USERS.add(loginUserVO);

        logger.info("用户已登录,useId:{},token:{}", loginId, tokenValue);
    }

    /** 每次注销时触发 */
    @Override
    public void doLogout(String loginType, Object loginId, String tokenValue) {
        ONLINE_USERS.removeIf(onlineUser ->
                onlineUser.getTokenValue().equals(tokenValue)
        );
        logger.info("用户已注销,useId:{},token:{}", loginId, tokenValue);
        System.out.println("---------- 自定义侦听器实现 doLogout");
    }

    /** 每次被踢下线时触发 */
    @Override
    public void doKickout(String loginType, Object loginId, String tokenValue) {
        ONLINE_USERS.removeIf(onlineUser ->
                onlineUser.getTokenValue().equals(tokenValue)
        );
        logger.info("用户已踢下线,useId:{},token:{}", loginId, tokenValue);
        System.out.println("---------- 自定义侦听器实现 doKickout");
    }

    /** 每次被顶下线时触发 */
    @Override
    public void doReplaced(String loginType, Object loginId, String tokenValue) {
        ONLINE_USERS.removeIf(onlineUser ->
                onlineUser.getTokenValue().equals(tokenValue)
        );
        logger.info("用户已顶下线,useId:{},token:{}", loginId, tokenValue);
        System.out.println("---------- 自定义侦听器实现 doReplaced");
    }

    /** 每次被封禁时触发 */
    @Override
    public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
        System.out.println("---------- 自定义侦听器实现 doDisable");
    }

    /** 每次被解封时触发 */
    @Override
    public void doUntieDisable(String loginType, Object loginId, String service) {
        System.out.println("---------- 自定义侦听器实现 doUntieDisable");
    }

    /** 每次二级认证时触发 */
    @Override
    public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
        System.out.println("---------- 自定义侦听器实现 doOpenSafe");
    }

    /** 每次退出二级认证时触发 */
    @Override
    public void doCloseSafe(String loginType, String tokenValue, String service) {
        System.out.println("---------- 自定义侦听器实现 doCloseSafe");
    }

    /** 每次创建Session时触发 */
    @Override
    public void doCreateSession(String id) {
        System.out.println("---------- 自定义侦听器实现 doCreateSession");
    }

    /** 每次注销Session时触发 */
    @Override
    public void doLogoutSession(String id) {
        System.out.println("---------- 自定义侦听器实现 doLogoutSession");
    }

    /** 每次Token续期时触发 */
    @Override
    public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
        System.out.println("---------- 自定义侦听器实现 doRenewTimeout");
    }
}
